
/**
* @fileoverview Handler crates a DOM structure for a slider table, dynamically
* fetches data from Google Fucion table and add their
* graphical representation into the slider table.     .
* @author honza.rychtar@gmail.com (Jan Rychtar)
*/

goog.provide('georeferencer.slider.Handler');


goog.require('goog.dom');
goog.require('goog.dom.xml');
goog.require('goog.net.XhrIo');
goog.require('goog.object');

goog.require('goog.ui.Control');
goog.require('goog.ui.decorate');
goog.require('goog.ui.registry');
goog.require('goog.ui.ControlRenderer');

goog.require('goog.fx.dom');

/**
 * Creates a new Handler.
 * @param {string} sql An sql query for Google Fusion Table.
 * @param {string} sliderDivID The id of div element where the slider table
 * is to be inserted.
 * @param {number} iframeHeight The height of slider table area.
 * @param {number=} opt_limit Number of records for a single request.
 * Defaults to 66.
 * @param {number=} opt_numberOfRows Number of rows of the slider table.
 * Defaults to 3.
 * @constructor
 */
georeferencer.slider.Handler = function(sql, sliderDivID, iframeHeight,
  opt_limit, opt_numberOfRows) {
  /**
   * @type {string}
   * @private
   */
  this.dbUrl_ = 'http://www.google.com/fusiontables/api/query';


  /**
   * @type {string}
   * @private
   */
  this.sql_ = sql;


  /**
   * @type {number}
   * @private
   */
  this.limit_ = goog.isDef(opt_limit) ? opt_limit : 66;

  /**
   * @type {number}
   * @private
   */
  this.numberOfRows_ = goog.isDef(opt_numberOfRows) ? opt_numberOfRows : 3;


  /**
   * @type {Element}
   * @private
   */
  this.draggingArea_ = goog.dom.createDom(goog.dom.TagName.DIV,
  {
    'id' : 'draggingArea', 
    'class': 'height100'
  });


  /**
   * @type {Array.<Element>}
   * @private
   */
  this.tableRows_ = new Array();


  /**
   * @type {Element}
   * @private
   */
  this.windowArea_ = goog.dom.createDom(goog.dom.TagName.DIV,
  {
    'id' : 'window'
  });

  this.createSliderTable_(sliderDivID, iframeHeight);

};


/**
 * @return {Element} The dragging area.
 */
georeferencer.slider.Handler.prototype.getDraggingArea = function() {
  return this.draggingArea_;
};


/**
 * @return {Element} The window area.
 */
georeferencer.slider.Handler.prototype.getWindowArea = function() {
  return this.windowArea_;
};


/**
 * @type {boolean}
 * @private
 */
georeferencer.slider.Handler.prototype.scrollLoading_ = false;


/**
 * @type {boolean}
 * @private
 */
georeferencer.slider.Handler.prototype.noMoreImages_ = false;


/**
 * @return {boolean} True if there are available records in
 * the google fusion table.
 */
georeferencer.slider.Handler.prototype.noMoreImages = function() {
  return this.noMoreImages_;
};


/**
 * @type {goog.ui.Component}
 * @private
 */
georeferencer.slider.Handler.prototype.leftButton_ = null;


/**
 * @type {goog.ui.Component}
 * @private
 */
georeferencer.slider.Handler.prototype.rightButton_ = null;


/**
 * @type {goog.ui.Component}
 * @private
 */
georeferencer.slider.Handler.prototype.leftEdge_ = null;


/**
 * @type {goog.ui.Component}
 * @private
 */
georeferencer.slider.Handler.prototype.rightEdge_ = null;


/**
 * @return {goog.ui.Component}
 */
georeferencer.slider.Handler.prototype.getRightButton = function() {
  return this.rightButton_;
};

/**
 * @return {goog.ui.Component}
 */
georeferencer.slider.Handler.prototype.getLeftButton = function() {
  return this.leftButton_;
};


/**
 * @return {goog.ui.Component}
 */
georeferencer.slider.Handler.prototype.getLeftEdge = function() {
  return this.leftEdge_;
};

/**
 * @return {goog.ui.Component}
 */
georeferencer.slider.Handler.prototype.getRightEdge = function() {
  return this.rightEdge_;
};


/**
 * Already fetched records counter
 * @type {number}
 * @private
 */
georeferencer.slider.Handler.prototype.counter_ = 0;



/**
 * @return {boolean} True while scrilling, false otherwise.
 */
georeferencer.slider.Handler.prototype.isScrollLoading = function() {
  return this.scrollLoading_;
};


/** @param {boolean} scrollLoading Set ScrollLoading flag.*/
georeferencer.slider.Handler.prototype.setScrollLoading = function(
  scrollLoading) {
  this.scrollLoading_ = scrollLoading;
};




georeferencer.slider.Handler.prototype.enableButtons = function() {                                                     
  this.leftButton_.setEnabled(true);
  this.rightButton_.setEnabled(true);
};
  

georeferencer.slider.Handler.prototype.disableButtons = function() {                                                     
  this.leftButton_.setEnabled(false);
  this.rightButton_.setEnabled(false);
};

  
/**
 * Crates a DOM structure for a slider table.
 * @param {string} sliderDivID The id of div element where the slider table
 * is to be inserted.
 * @param {number} iframeHeight The height of slider table area.
 * @private
 */
georeferencer.slider.Handler.prototype.createSliderTable_ =
  function(sliderDivID, iframeHeight) {

    var table = goog.dom.createDom(goog.dom.TagName.TABLE, {
      'class' : 'canvas'
    });
    var tbody = goog.dom.createDom(goog.dom.TagName.TBODY);

    var styleHeight = 'height: ' + iframeHeight + 'px';
    var wrapper = goog.dom.createDom(goog.dom.TagName.DIV,
    {
      'id' : 'wrapper', 
      'style' : styleHeight
    });

    var leftEdgeDiv = goog.dom.createDom(goog.dom.TagName.DIV,
    {
      'id' : 'leftEdge', 
      'class' : 'side-edge left-edge goog-control'
    });
    leftEdgeDiv.style.height=iframeHeight - 18 + "px";
  
    var rightEdgeDiv = goog.dom.createDom(goog.dom.TagName.DIV,
    {
      'id' : 'rightEdge', 
      'class' : 'side-edge right-edge goog-control'
    });      
    rightEdgeDiv.style.height=iframeHeight - 18 + "px";       

    var leftButtonDiv = goog.dom.createDom(goog.dom.TagName.DIV,
    {
      'id' : 'leftButton', 
      'class' : 'button left-button goog-control'
    });

    var rightButtonDiv = goog.dom.createDom(goog.dom.TagName.DIV,
    {
      'id' : 'rightButton', 
      'class' : 'button right-button goog-control'
    });

    var top = Math.round((iframeHeight/2));  
    leftButtonDiv.style.top=top + 'px';
    rightButtonDiv.style.top=top + 'px';

    goog.dom.appendChild(goog.dom.getElement(sliderDivID), wrapper);
    goog.dom.appendChild(this.windowArea_, this.draggingArea_);
    goog.dom.appendChild(this.draggingArea_, leftEdgeDiv);
    goog.dom.appendChild(this.draggingArea_, rightEdgeDiv);
    goog.dom.appendChild(leftEdgeDiv, leftButtonDiv);
    goog.dom.appendChild(rightEdgeDiv, rightButtonDiv);
    goog.dom.appendChild(wrapper, this.windowArea_);
    goog.dom.appendChild(this.draggingArea_, table);
    goog.dom.appendChild(table, tbody);

    for (var i = 0; i < this.numberOfRows_; i++) {
      this.tableRows_[i] = goog.dom.createDom(goog.dom.TagName.TR,
      {
        'valign' : 'middle'
      });
      goog.dom.appendChild(tbody, this.tableRows_[i]);
    }
  
    this.leftEdge_ = goog.ui.decorate(goog.dom.getElement('leftEdge'));
    this.rightEdge_ = goog.ui.decorate(goog.dom.getElement('rightEdge'));
    this.leftButton_ = goog.ui.decorate(goog.dom.getElement('leftButton'));
    this.rightButton_ = goog.ui.decorate(goog.dom.getElement('rightButton'));          
    this.leftEdge_.setVisible(false);        
  };


/**
 * Public method for fetching another batch of records.
 */
georeferencer.slider.Handler.prototype.getMoreImages = function() {
  var url = this.dbUrl_ + '?sql=' + this.sql_ + '+OFFSET+' + this.counter_ +
  '+LIMIT+' + this.limit_ + '&jsonCallback=getData';
  var script = document.createElement('script');
  script.setAttribute('src', url);
  document.getElementsByTagName('head')[0].appendChild(script);
};


/**
 * The function handles new records.
 * @param {Object} data Data from Google Fusion Table.
 */
georeferencer.slider.Handler.prototype.newBatch = function(data) {
  var matrix = data['table']['rows'];
  for (var i = 0; i < this.limit_; i++) {
    if (matrix[i] == null) {
      this.noMoreImages_ = true;
      return;
    } else {
      var titleString = matrix[i][0];
      var linkString = matrix[i][2];
      var imageString = matrix[i][3];
      var item = new Array(titleString, linkString, imageString);
      this.insert_(item);
    }
  }
  this.scrollLoading_ = false;
};


/**
 * @param {Element} row The row of the slider table.
 * @param {Array.<string>} item An Array representation of a record
 * that is to be inserted.
 * @private
 */

georeferencer.slider.Handler.prototype.insertToRow_ = function(row, item) {
  var imgAttributes = {
    'src' : item[2],
    'class' : 'list-img',
    'alt' : item[0],
    'title' : item[0]
  };
  var aAttributes = {
    'href' : item[1],
    'target' : '_parent',
    'class' : 'list-a'
  };

  var imgEl = goog.dom.createDom('img', imgAttributes);
  var aEl = goog.dom.createDom('a', aAttributes, imgEl);  
  
  goog.events.listen(imgEl,
    goog.events.EventType.MOUSEOVER,
    function(e) {      
      //var anim = new goog.fx.dom.FadeInAndShow(e.target, 450);
      var anim = new goog.fx.dom.Fade(e.target, [0.3], [1.0], 1000);
      goog.events.listen(anim, goog.fx.Animation.EventType.BEGIN, function (e) {});
      goog.events.listen(anim, goog.fx.Animation.EventType.END,function (e) {});
      anim.play();                           
    });                                             
  aEl.onclick = new Function('return georeferencer.slider.isLinkEnabled();');

  var tdEl = goog.dom.createDom('td', null, aEl);
  goog.dom.appendChild(row, tdEl);
};


/**
 * @param {Array.<string>} item An Array representation of a record
 * that is to be inserted.
 * @private
 */
georeferencer.slider.Handler.prototype.insert_ = function(item) {
  var rowNumber = this.counter_ % this.numberOfRows_;
  this.counter_++;
  this.insertToRow_(this.tableRows_[rowNumber], item);
};
